/*
 * @Description: 树形控件
 * @Version: V1.0.0
 * @Author: 黄鑫
 * @Date: 2025-03-27
 * @LastEditors: 黄鑫
 * @LastEditTime: 2025-08-21
 * @FilePath: TreeScreen.dart
 * @Remarks: 
 */
import 'package:flutter/material.dart';
import 'package:get/route_manager.dart';
import 'package:hx_base/pages/tree/TreeModel.dart';

class TreeScreen extends StatefulWidget {
  // 结构树
  TreeModel root;

  // 已选择的数据
  TreeModel chooseItem;

  // 回调
  Function(TreeModel item) callBack;

  TreeScreen(
      {super.key,
      required this.root,
      required this.chooseItem,
      required this.callBack});

  @override
  State<TreeScreen> createState() => _TreeScreenState();
}

class _TreeScreenState extends State<TreeScreen> {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Container(
          padding: EdgeInsets.symmetric(horizontal: 10),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              TextButton(
                  onPressed: () {
                    Get.back();
                  },
                  child: Text("取消")),
              TextButton(
                  onPressed: () {
                    widget.callBack(widget.chooseItem);
                    Get.back();
                  },
                  child: Text("确定")),
            ],
          ),
        ),
        Expanded(
          child: SingleChildScrollView(
            child: NodeWidget(
              widget.root,
              widget.chooseItem,
              onNodeDataChanged: (item) {
                widget.chooseItem = item;
                setState(() {});
              },
            ),
          ),
        ),
      ],
    );
  }
}

// 每条的数据布局
class NodeWidget extends StatefulWidget {
  TreeModel tree;
  TreeModel chooseTree;

  Function(TreeModel item) onNodeDataChanged;

  NodeWidget(
    this.tree,
    this.chooseTree, {
    super.key,
    required this.onNodeDataChanged,
  });

  @override
  State<NodeWidget> createState() => _NodeWidgetState();
}

class _NodeWidgetState extends State<NodeWidget>
    with SingleTickerProviderStateMixin {
  // 动画
  late AnimationController rotationController;

  final Tween<double> _turnsTween = Tween<double>(begin: -0.25, end: 0.0);

  @override
  void initState() {
    super.initState();
    rotationController = AnimationController(
      duration: const Duration(milliseconds: 300),
      vsync: this,
    );
    if (widget.tree.isExpanded) {
      rotationController.forward();
    }
  }

  @override
  void dispose() {
    rotationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        buildNode(),
        buildChildrenNodes(),
      ],
    );
  }

  /* -----数据------- */
  Widget buildNode() {
    if (!(widget.tree.isShow)) return const SizedBox.shrink();
    return GestureDetector(
      onTap: () {
        if (widget.tree.isDisabled) {
          return;
        }
        updateTreeSingleChoiceDms4(widget.tree);
        // 点击数据回调
        widget.onNodeDataChanged(widget.tree);
      },
      child: Row(
        children: [
          Expanded(
              child: Container(
            decoration: BoxDecoration(
              borderRadius: const BorderRadius.all(Radius.circular(5)),
              color: Colors.transparent,
            ),
            padding: const EdgeInsets.symmetric(horizontal: 6.0, vertical: 13),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Expanded(
                  child: Text(
                    widget.tree.name,
                    maxLines: 1,
                    overflow: TextOverflow.ellipsis,
                    style: TextStyle(
                      color: widget.tree.isDisabled
                          ? Color(0xFF828384)
                          : (widget.tree.isChoose
                              ? Colors.green
                              : Colors.black),
                    ),
                  ),
                ),
                Visibility(
                    visible: widget.tree.isChoose,
                    child: Icon(
                      Icons.check,
                      color: Colors.green,
                      size: 20,
                    ))
              ],
            ),
          )),
          Visibility(
            visible: widget.tree.children.isNotEmpty,
            child: RotationTransition(
              turns: _turnsTween.animate(rotationController),
              child: IconButton(
                iconSize: 16,
                icon: const Icon(Icons.expand_more, size: 16.0),
                onPressed: () {
                  widget.tree.isExpanded = !widget.tree.isExpanded;
                  widget.tree.isExpanded
                      ? rotationController.forward()
                      : rotationController.reverse();
                },
              ),
            ),
          ),
        ],
      ),
    );
  }

// 更新选择状态
  updateTreeSingleChoiceDms4(TreeModel tree) {
    var root = findRoot(tree);
    uncheckALl(root);
    tree.isChoose = true;
  }

  // 查找根节点
  TreeModel findRoot(TreeModel tree) {
    if (tree.isRoot) return tree;
    return findRoot(tree.parent!);
  }

  // 清除选择状态
  uncheckALl(TreeModel tree) {
    tree.isChoose = false;
    for (var element in tree.children) {
      uncheckALl(element);
    }
  }

  /*  -----子级数据------- */

  Widget buildChildrenNodes(
      {final EdgeInsets? padding = const EdgeInsets.only(left: 12)}) {
    return SizeTransition(
      sizeFactor: rotationController,
      child: Padding(
        padding: padding ?? EdgeInsets.zero,
        child: Column(
          children: generateChildrenNodesWidget(widget.tree.children),
        ),
      ),
    );
  }

  List<Widget> generateChildrenNodesWidget(List<TreeModel> list) =>
      List.generate(
        list.length,
        (int index) => NodeWidget(
          list[index],
          widget.chooseTree,
          onNodeDataChanged: widget.onNodeDataChanged,
        ),
      );
}
